package com.jar.exercise.关于String的面试题;

import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.*;

/**
 * <div  style="border:2px solid none;margin:20px;padding:15px;font-size:24px;text-align:center;color:aqua;">
 *
 *
 *
 *  </div>
 *
 * @author zhangshun
 * @date 2021/5/8 18:32
 */
@Slf4j
public class 读取文件中的字符串 {

    static int fileSum = 10;

    static String resultPath = "F:\\files\\tem%d\\";

    static String resultFile = "result%d.txt";

    static String temPath = "F:\\files\\tem%d.txt";


    static Map<Integer, BufferedWriter> writers = new HashMap<>();


    static {
        for (int i = 0; i < fileSum; i++) {
            try {

                final File file = new File(String.format(resultPath, 0));
                if (!file.exists()) {
                    file.mkdirs();
                }

                writers.put(i, new BufferedWriter(new FileWriter(String.format(resultPath + resultFile ,0, i))));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws IOException {

        FileReader fileReader = new FileReader("F:\\files\\tem0.txt");
        BufferedReader bufferedReader = new BufferedReader(fileReader);

        String line;

        while ((line = bufferedReader.readLine()) != null){
            System.out.println("获取行上的值：" + line);
            final int i = Math.abs(hash(line)) % fileSum;
            System.out.println("取模的值："+i);
            final BufferedWriter bufferedWriter1 = writers.get(i);
            bufferedWriter1.write(line + "\n");
            bufferedWriter1.flush();
        };


    }


    private static int hash(String str) {
        int h = 0;
        int off = 0;
        char[] val = str.toCharArray();
        int len = str.length();

        for (long i = 0; i < len; i++) {
            h = 31 * h + val[off++];
        }
        return h;
    }

}



class Prepare{
    public static void main(String[] args) throws IOException {
        Random random = new Random();

        FileWriter fileWriter = new FileWriter("F:\\files\\ip.txt" ,true);
        BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);

        for (int i = 0; i < 600000000; i++) {
            bufferedWriter
                    .append(String.valueOf(random.nextInt(255)))
                    .append(".")
                    .append(String.valueOf(random.nextInt(255)))
                    .append(".")
                    .append(String.valueOf(random.nextInt(255)))
                    .append(".")
                    .append(String.valueOf(random.nextInt(255)))
                    .append("\n");
        }
        bufferedWriter.flush();
        bufferedWriter.close();

    }
}



class FileLines{
    static String path = "F:\\files\\ip.txt";

    public static void main(String[] args) throws IOException, InterruptedException {
        Thread.sleep(10000);
        System.out.println(Files.lines(Paths.get(path)).count());
    }

}


class SplitFile {


    static ExecutorService executorService = new ThreadPoolExecutor(
            20 ,
            20 ,
            20,
            TimeUnit.MILLISECONDS ,
            new LinkedBlockingDeque<>(500) ,
            new ThreadPoolExecutor.DiscardPolicy()
    );

    static String path = "F:\\files\\ip.txt";

    static String temPath = "F:\\files\\tem%d.txt";

    static Map<Integer, BufferedWriter> writers = new HashMap<>();

    static int fileSum = 100;

    static {


        for (int i = 0; i < fileSum; i++) {
            try {
                writers.put(i, new BufferedWriter(new FileWriter(String.format(temPath , i))));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws IOException {

        System.out.println("开始时间 " + System.currentTimeMillis());
        write(Files.lines(Paths.get(path)).count());
        System.out.println("结束时间 " + System.currentTimeMillis());


    }


    public static void write(long sumLine) throws IOException {
        final LineNumberReader lineNumberReader = new LineNumberReader(new FileReader(path));

        lineNumberReader.setLineNumber(0);

        int num;
        while ((num = lineNumberReader.getLineNumber()) < sumLine) {
            final String s = lineNumberReader.readLine();

            int finalNum = num;
            executorService.execute(() -> {
                final BufferedWriter bufferedWriter = writers.get(finalNum % fileSum);
                try {
                    bufferedWriter.write(s);
                    bufferedWriter.newLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
        }
        close();
    }

    public static void close(){
        writers.forEach((k, v) -> {
                    try {
                        v.flush();
                        v.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });
        executorService.shutdown();
    }

    /**
     *  去重
     */
    static class DeDuplication{

        static String path = "F:\\files\\tem0\\result%d.txt";

        public static void main(String[] args) throws IOException {

            for (int i = 0; i < 10; i++) {
                doDuplication(i);
            }

        }


        static void doDuplication(int index) throws IOException{
            System.out.println("开始前数量:" + Files.lines(Paths.get(String.format(path, index))).count());

            FileReader fileReader = new FileReader(String.format(path, index));

            Set<String> set = new HashSet<>();

            try (BufferedReader bufferedReader = new BufferedReader(fileReader)) {
                String line;
                while ((line = bufferedReader.readLine()) != null) {
                    set.add(line);
                }
            }
            fileReader.close();

            System.out.println("处理后的数据量:" + set.size());
            FileWriter fieldWriter = new FileWriter(String.format(path, index));
            try (BufferedWriter bufferedWriter = new BufferedWriter(fieldWriter)) {
                for (String str : set) {
                    bufferedWriter.write(str);
                    bufferedWriter.newLine();
                }
                bufferedWriter.flush();
            }
            fieldWriter.close();
            System.out.println("结束时数量:" + Files.lines(Paths.get(String.format(path, index))).count());
        }


    }

}